<?php
/**
 * Created by PhpStorm.
 * User: GadflyBSD
 * Date: 16/3/14
 * Time: 14:23
 */
function pre($arr){
	echo "<pre>";
	print_r($arr);
	echo "</pre>";
}

/**
 * 返回一个值,如果该值在$array范围内则返回该值,否则返回$default
 * @param $param
 * @param $array
 * @param $default
 *
 * @return mixed
 */
function defaultParam($param, $array, $default){
	return in_array($param, $array)?$param:$default;
}

/**
 * 将一个数值按百分比形式输出,百分数精确到小数点后两位,超出部分舍弃
 * @param $num
 *
 * @return string
 */
function percentage($num){
	return (floor($num * 10000)/10000 * 100) ."%";
}

/**
 * 功能：对字符串进行加密处理
 * @param        $string        需要加密的内容
 * @param string $operation     判断是加密还是解密，E表示加密，D表示解密
 * @param string $key           密钥
 *
 * @return mixed|string
 */
function strcrypt($string, $operation='D', $key=''){
	$secret=md5($key != '' ? $key : C('AUTHKEY'));
	if($operation=='E'){
		srand((double)microtime() * 1000000);
		$encrypt_key=md5(rand(0, 32000));
		$ctr=0;
		$tmp='';
		for($i=0;$i<strlen($string);$i++){
			$ctr=$ctr==strlen($encrypt_key)?0:$ctr;
			$tmp.=$encrypt_key[$ctr].($string[$i] ^ $encrypt_key[$ctr++]);
		}
		return str_replace('=','',base64_encode(passport_key($tmp, $secret)));
	}else{
		$str=passport_key(base64_decode($string), $secret);
		$tmp='';
		for($i=0;$i<strlen($str);$i++){
			$md5=$str[$i];
			$tmp.=$str[++$i] ^ $md5;
		}
		return $tmp;
	}
}

/*
*辅助函数
*/
function passport_key($str,$encrypt_key){
	$encrypt_key=md5($encrypt_key);
	$ctr=0;
	$tmp='';
	for($i=0;$i<strlen($str);$i++){
		$ctr=$ctr==strlen($encrypt_key)?0:$ctr;
		$tmp.=$str[$i] ^ $encrypt_key[$ctr++];
	}
	return $tmp;
}

function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
	$ckey_length = 4;

	$key = md5($key ? $key : C('AUTHKEY'));
	$keya = md5(substr($key, 0, 16));
	$keyb = md5(substr($key, 16, 16));
	$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

	$cryptkey = $keya.md5($keya.$keyc);
	$key_length = strlen($cryptkey);

	$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	$string_length = strlen($string);

	$result = '';
	$box = range(0, 255);

	$rndkey = array();
	for($i = 0; $i <= 255; $i++) {
		$rndkey[$i] = ord($cryptkey[$i % $key_length]);
	}

	for($j = $i = 0; $i < 256; $i++) {
		$j = ($j + $box[$i] + $rndkey[$i]) % 256;
		$tmp = $box[$i];
		$box[$i] = $box[$j];
		$box[$j] = $tmp;
	}

	for($a = $j = $i = 0; $i < $string_length; $i++) {
		$a = ($a + 1) % 256;
		$j = ($j + $box[$a]) % 256;
		$tmp = $box[$a];
		$box[$a] = $box[$j];
		$box[$j] = $tmp;
		$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
	}

	if($operation == 'DECODE') {
		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
			return substr($result, 26);
		} else {
			return '';
		}
	} else {
		return $keyc.str_replace('=', '', base64_encode($result));
	}

}

/**
 * @param        $string        需要加密解密的字符串
 * @param        $operation     判断是加密还是解密，E表示加密，D表示解密
 * @param string $key           密匙
 *
 * @return mixed|string
 */
function encrypt($string, $operation, $key=''){
	$key=md5($key != '' ? $key : C('AUTHKEY'));
	$key_length=strlen($key);
	$string=$operation=='D'?base64_decode($string):substr(md5($string.$key),0,8).$string;
	$string_length=strlen($string);
	$rndkey=$box=array();
	$result='';
	for($i=0;$i<=255;$i++){
		$rndkey[$i]=ord($key[$i%$key_length]);
		$box[$i]=$i;
	}
	for($j=$i=0;$i<256;$i++){
		$j=($j+$box[$i]+$rndkey[$i])%256;
		$tmp=$box[$i];
		$box[$i]=$box[$j];
		$box[$j]=$tmp;
	}
	for($a=$j=$i=0;$i<$string_length;$i++){
		$a=($a+1)%256;
		$j=($j+$box[$a])%256;
		$tmp=$box[$a];
		$box[$a]=$box[$j];
		$box[$j]=$tmp;
		$result.=chr(ord($string[$i])^($box[($box[$a]+$box[$j])%256]));
	}
	if($operation=='D'){
		if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8)){
			return substr($result,8);
		}else{
			return'';
		}
	}else{
		return str_replace('=','',base64_encode($result));
	}
}

/**
 * 编码加密数组或解码解密数据
 * @param $param    需要加密的数组数据，或需要解码解密的数据
 * @param $token    加密解密密匙
 * @param $operation    加密（ENCODE）或解密（DECODE），默认加密
 *
 * @return string   返回编码加密后的数据，或解码解密后的数据
 */
function encryptcode($param, $token, $operation='ENCODE'){
	$secret = hash_hmac("sha256", md5(C('AUTHKEY')), $token);
	if($operation=='ENCODE'){
		$encode = authcode(serialize($param), $operation);
		$string = encrypt($encode.'&secret='.$secret, 'E', $secret);
		return urlencode(base64_encode($string));
	}elseif($operation=='DECODE'){
		$decode = base64_decode(urldecode($param));
		$string = encrypt($decode, 'D', $secret);
		$data = explode('&secret=', $string);
		if($data[1] == $secret)
			return unserialize(authcode($data[0], $operation));
		else
			return false;
	}
}

function uploadName($filename){
	$ext = pathinfo($filename);
	if (in_array($ext['extension'], array('jpg', 'gif', 'png', 'bmp')))
		return md5(basename($filename, $ext['extension']).time()).'.'.$ext['extension'];
	else
		return false;
}

/**
 * 获取图片的缩略图地址,缩略图不存在时自动创建
 * @param $file     原图路径和文件,支持远程文件
 * @param $width    缩略图宽
 * @param $height   缩略图高
 *
 * @return string
 */
function imgSrc($file, $width, $height){
	$ext = isImage((preg_match('/^http:\/\//',$file))?$file:C('UPLOAD_PATH').$file);
	if($ext){
		$info = pathinfo($file);
		$thumbFile = $info['filename'].'_'.$width.'x'.$height.'.'.$ext;
		$thumbPath = C('STATIC_PATH').$info['dirname'].'/';
		if(!file_exists($thumbPath)){
			mkdirs($thumbPath, 0755, true);
		}
		if(!is_file($thumbPath.$thumbFile)){
			import('ORG.Util.Image.ThinkImage');
			$img = new ThinkImage(THINKIMAGE_GD, C('UPLOAD_PATH').$file);
			$img->thumb($width, $height, THINKIMAGE_THUMB_FILLED)->save($thumbPath.$thumbFile);
		}
		return C('PROTOCOL').'://'.C('STATIC_URL').$info['dirname'].'/'.$thumbFile;
	}else{
		return 'http://placehold.it/'.$width.'x'.$height;
	}
}

/**
 * 检查文件的存在性，远程或是本地文件均可，不必考虑是否禁用了allow_url_open
 * @param $file
 *
 * @return bool
 */
function fileExists($file){
	if(preg_match('/^http:\/\//',$file)){
		if(ini_get('allow_url_fopen')){
			if(@fopen($file,'r')) return true;
		}else{
			$parseurl=parse_url($file);
			$host=$parseurl['host'];
			$path=$parseurl['path'];
			$fp=fsockopen($host,80, $errno, $errstr, 10);
			if(!$fp)return false;
			fputs($fp,"GET {$path} HTTP/1.1 \r\nhost:{$host}\r\n\r\n");
			if(preg_match('/HTTP\/1.1 200/',fgets($fp,1024))) return true;
		}
		return false;
	}
	return file_exists($file);
}

/**
 * 判断一个文件是否是图片类型
 * @param $file
 *
 * @return bool|string
 */
function isImage($file){
	if(!extension_loaded('gd')){
		$fp = fopen($file, "rb");
		$bin = fread($fp, 2);
		fclose($file);
		$strInfo = @unpack("C2chars", $bin);
		$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
		switch($typeCode){
			case 255216:
				return 'jpg';
			case 7173:
				return 'gif';
			case 6677:
				return 'bmp';
			case 13780:
				return 'png';
			default:
				return false;
		}
	}else{
		switch(exif_imagetype($file)){
			case IMAGETYPE_GIF:
				return 'gif';
			case IMAGETYPE_JPEG:
				return 'jpg';
			case IMAGETYPE_PNG:
				return 'png';
			case IMAGETYPE_BMP:
				return 'bmp';
			default:
				return false;
		}
	}
}

function mkdirs($dir){
	if(!is_dir($dir)){
		if(!mkdirs(dirname($dir))){
			return false;
		}
		if(!mkdir($dir,0777)){
			return false;
		}
	}
	return true;
}

function rmFile($path, $fileName=''){
	$path = preg_replace('/(\/){2,}|{\\\}{1,}/','/',$path);     //去除空格
	$path.= $fileName;      //得到完整目录
	if(is_dir($path)){      //判断此文件是否为一个文件目录
		if ($dh = opendir($path)){      //打开文件
			while (($file = readdir($dh)) != false){        //遍历文件目录名称
				unlink($path.'\\'.$file);       //逐一进行删除
			}
			closedir($dh);      //关闭文件
		}
	}
}

function money($money, $type='floor'){
	if($type=='floor')
		return floor($money*100)/100;
	else
		return round($money, 2);
}

function randstr($len=6, $chars='abcdefghijklmnopqrstuvwxyz0123456789'){
	mt_srand((double)microtime()*1000000*getmypid());
	$randstr='';
	while(strlen($randstr)<$len)
		$randstr.=substr($chars,(mt_rand()%strlen($chars)),1);
	return $randstr;
}

function rfile($filename){
	$handle = fopen($filename, "r");
	$contents = fread($handle, filesize ($filename));
	fclose($handle);
	return $contents;
}

function wfile($filename, $content){
	if (!$handle = fopen($filename, 'w')) {
		return "���ܴ��ļ� $filename";
		exit;
	}
	if (fwrite($handle, $content) === FALSE) {
		return "����д�뵽�ļ� $filename";
		exit;
	}
	return "�ɹ�д�뵽�ļ�$filename";
	fclose($handle);
}

function getMicrotime($len = 3){
	list($usec, $sec) = explode(" ", microtime());
	return substr($usec, 2, $len);
}

function is_json($string) {
	json_decode($string);
	return (json_last_error() == JSON_ERROR_NONE);
}

function isActive($param, $active='active'){
	if(is_string($param)){
		$param = explode('/', $param);
		if($param[0] != '*')
			if($param[0] != ACTION_NAME) return '';
		if($param[1] != '*')
			if($param[1] != MODULE_NAME) return '';
		if($param[2] != '*')
			if($param[2] != GROUP_NAME) return '';
		if($param[3] != THEME_NAME) return '';
		return $active;
	}
	if(is_array($param)){
		if($param[0] != $param[1])
			return '';
		else
			return $active;
	}
}

/**
 * CURL GET方式获取http页面数据，非SSL加密
 * @param string $url
 * @return mixed
 */
function curlGet($url, $ssl=false){
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_URL,$url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_TIMEOUT, 500);
	if($ssl){
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	}
	$data = curl_exec($ch);
	curl_close($ch);
	if($data)
		return $data;
	else
		echo "<br/>请求失败！<br/>";
}

/**
 * CURL POST方式向http页面提交数据并获取返回数据，非SSL加密
 * @param string $url
 * @param string $postdata
 * @return mixed
 */
function curlPostHeader($url, $postdata, $ssl=false){
	$header=array('Content-Type:text/xml;charset=UTF-8',);
	$url .= '?'.http_build_query($postdata);
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
	curl_setopt($ch, CURLOPT_TIMEOUT, 500);
	if($ssl){
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
	}
	curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
	$data = curl_exec($ch);
	curl_close($ch);
	if($data)
		return $data;
	else
		echo "<br/>请求失败！<br/>";
}

function curlPost($url, $postdata, $ssl=false){
	//$url .= '?'.http_build_query($postdata);
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
	curl_setopt($ch, CURLOPT_TIMEOUT, 500);
	if($ssl){
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	}
	$data = curl_exec($ch);
	curl_close($ch);
	if($data)
		return $data;
	else
		echo "<br/>请求失败！<br/>";
}

function snoopyPost($url, $postdata){
	Vendor('Snoopy');
	$Snoopy = new Snoopy();
	$Snoopy->submit($url, $postdata);
	return $Snoopy->results;
}

function snoopyGet($url, $getdata){
	Vendor('Snoopy');
	$Snoopy = new Snoopy();
	$Snoopy->fetch($url.'?'.$getdata);
	return $Snoopy->results;
}

/**
 * 返回中文不进行编码和路径不加斜杠的json格式数据, 针对PHP 5.4以上或以下均有效
 * @param $array
 *
 * @return mixed|string
 */
function json_encode_plus($array){
	if(version_compare(PHP_VERSION, '5.4.0') >= 0){
		return json_encode($array, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
	}else{
		arrayRecursive($array, 'urlencode', true);
		return str_replace("\\/", "/", urldecode(json_encode($array)));
	}
}

//对象转数组,使用get_object_vars返回对象属性组成的数组
function objectToArray($obj){
	$arr = is_object($obj) ? get_object_vars($obj) : $obj;
	if(is_array($arr)){
		return array_map(__FUNCTION__, $arr);
	}else{
		return $arr;
	}
}

//数组转对象
function arrayToObject($arr){
	if(is_array($arr)){
		return (object) array_map(__FUNCTION__, $arr);
	}else{
		return $arr;
	}
}

function arrayRecursive(&$array, $function, $apply_to_keys_also = false){
	static $recursive_counter = 0;
	if (++$recursive_counter > 1000) {
		die('possible deep recursion attack');
	}
	foreach($array as $key => $value){
		if(is_array($value)){
			arrayRecursive($array[$key], $function, $apply_to_keys_also);
		}else{
			$array[$key] = $function($value);
		}
		if($apply_to_keys_also && is_string($key)){
			$new_key = $function($key);
			if ($new_key != $key) {
				$array[$new_key] = $array[$key];
				unset($array[$key]);
			}
		}
	}
	$recursive_counter--;
}

/**
 * 编码转化函数，主要用于进行编码的转化
 * @param $m
 * @param $from
 * @param $to
 * @return string
 */
function convert_encoding($m, $from, $to) {
	switch(gettype($m)) {
		case 'integer':
		case 'boolean':
		case 'float':
		case 'double':
		case 'NULL':
			return $m;
		case 'string':
			return iconv($from, $to, $m);
		case 'object':
			$vars = array_keys(get_object_vars($m));
			foreach($vars as $key) {
				$m->$key = convert_encoding($m->$key, $from ,$to);
			}
			return $m;
		case 'array':
			foreach($m as $k => $v) {
				$m[convert_encoding($k, $from, $to)] = convert_encoding($v, $from, $to);
			}
			return $m;
		default:
	}
	return $m;
}

function checkMobile($mobile){
	if (preg_match('/^(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1}))+\d{8})$/', $mobile))
		return true;
	else
		return false;
}

function formDefault($param, $value, $out='check'){
	if($param == $value) return $out;
}

function _transcoding($param, $to = 'D2P'){
	if(C('DB_CHARSET') != C('DEFAULT_CHARSET')){
		if($to == 'D2P') return convert_encoding($param, C('DB_CHARSET'), C('DEFAULT_CHARSET'));
		elseif($to == 'P2D') return convert_encoding($param, C('DEFAULT_CHARSET'), C('DB_CHARSET'));
		else return $param;
	}else{
		return $param;
	}
}

function _stripslashes($string) {
	if(is_array($string)) {
		foreach($string as $key => $val) {
			$string[$key] = _stripslashes($val);
		}
	} else {
		$string = stripslashes($string);
	}
	return $string;
}

function validation_filter_id_card($id_card)
{
	if(strlen($id_card) == 18)
	{
		return idcard_checksum18($id_card);
	}
	elseif((strlen($id_card) == 15))
	{
		$id_card = idcard_15to18($id_card);
		return idcard_checksum18($id_card);
	}
	else
	{
		return false;
	}
}
// 计算身份证校验码，根据国家标准GB 11643-1999
function idcard_verify_number($idcard_base)
{
	if(strlen($idcard_base) != 17)
	{
		return false;
	}
	//加权因子
	$factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
	//校验码对应值
	$verify_number_list = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
	$checksum = 0;
	for ($i = 0; $i < strlen($idcard_base); $i++)
	{
		$checksum += substr($idcard_base, $i, 1) * $factor[$i];
	}
	$mod = $checksum % 11;
	$verify_number = $verify_number_list[$mod];
	return $verify_number;
}
// 将15位身份证升级到18位
function idcard_15to18($idcard){
	if (strlen($idcard) != 15){
		return false;
	}else{
		// 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码
		if (array_search(substr($idcard, 12, 3), array('996', '997', '998', '999')) !== false){
			$idcard = substr($idcard, 0, 6) . '18'. substr($idcard, 6, 9);
		}else{
			$idcard = substr($idcard, 0, 6) . '19'. substr($idcard, 6, 9);
		}
	}
	$idcard = $idcard . idcard_verify_number($idcard);
	return $idcard;
}
// 18位身份证校验码有效性检查
function idcard_checksum18($idcard){
	if (strlen($idcard) != 18){ return false; }
	$idcard_base = substr($idcard, 0, 17);
	if (idcard_verify_number($idcard_base) != strtoupper(substr($idcard, 17, 1))){
		return false;
	}else{
		return true;
	}
}

function utf8_strlen($string = null) {
	// 将字符串分解为单元
	preg_match_all("/./us", $string, $match);
	return count($match[0]);
}

function dataSecrecy($data, $type='mobile', $str='****'){
	switch($type){
		case 'mobile':
			$pattern = '/(1\d{1,2})\d\d(\d{0,3})/';
			$replacement = '\$1'.$str.'\$3';
			break;
		case 'ip':
			$pattern = '~(\d+)\.(\d+)\.(\d+)\.(\d+)~';
			$replacement = '$1.$2.*.*';
			break;
		case 'idcard':
			$pattern = '/(\d{0,5})\d\d(\d{0,3})/';
			$replacement = '\$1'.$str.$str.'\$3';
			break;
		case 'bankCode':
			$pattern = '/(\d{0,3})\d\d(\d{0,3})/';
			$replacement = '\$1 '.$str.' '.$str.' \$3';
			break;
	}
	return preg_replace($pattern, $replacement, $data);
}

function Event($action, $param=null){
	Vendor('ActionEvent');
	$event = new ActionEvent();
	return $event->run($action, $param);
}

function make_cors($origin = '*') {
	$request_method = $_SERVER['REQUEST_METHOD'];
	if ($request_method === 'OPTIONS') {
		header('Access-Control-Allow-Origin:'.$origin);
		header('Access-Control-Allow-Credentials:true');
		header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
		header('Access-Control-Max-Age:1728000');
		header('Content-Type:text/plain charset=UTF-8');
		header('Content-Length: 0',true);
		header('status: 204');
		header('HTTP/1.0 204 No Content');
	}
	if ($request_method === 'POST') {
		header('Access-Control-Allow-Origin:'.$origin);
		header('Access-Control-Allow-Credentials:true');
		header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
	}
	if ($request_method === 'GET') {
		header('Access-Control-Allow-Origin:'.$origin);
		header('Access-Control-Allow-Credentials:true');
		header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
	}
}

function saveMedia($url, $dirname){
	$ch = curl_init($url);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_NOBODY, 0);    //对body进行输出。
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	$package = curl_exec($ch);
	$httpinfo = curl_getinfo($ch);
	curl_close($ch);
	$media = array_merge(array('mediaBody' => $package), $httpinfo);
	preg_match('/\w\/(\w+)/i', $media["content_type"], $extmatches);
	$fileExt = $extmatches[1];
	$filename = time().rand(100,999).".{$fileExt}";
	$targetPath = $dirname.date('/Ym/d/');
	if(!file_exists(realpath($targetPath))) mkdirs(realpath($targetPath), 0755, true);
	file_put_contents(realpath($targetPath).$filename, $media['mediaBody']);
	return $targetPath.$filename;
}

function logic($name){
	return D($name, 'Logic');
}